using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;


namespace _3D_Game2
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class ModelManager : DrawableGameComponent
    {

        List<BasicModel> models = new List<BasicModel>();
            // Spawn variables
            Vector3 maxSpawnLocation = new Vector3(10000, 10000, -10000);
            int nextSpawnTime = 0;
            int timeSinceLastSpawn = 0;
            float maxRollAngle = MathHelper.Pi / 40;
            // Enemy count
            int enemiesThisLevel = 0;
            // Misses variables
            int missedThisLevel = 0;
            // Current level
            int currentLevel = 5;
            // List of LevelInfo objects
            List<LevelInfo> levelInfoList = new List<LevelInfo>( );
            Boolean nextenemy = false;

        List<BasicModel> shots = new List<BasicModel>( );
        
        //myshots
        //List<BasicModel> myshots = new List<BasicModel>();


        float shotMinZ = - 10000;

        //Kobala the player Model;
        Kobala myKobala;
 
        
        public ModelManager(Game game)
            : base(game)
        {
            // Initialize game levels
            levelInfoList.Add(new LevelInfo(1000, 3000, 20, 2, 6, 10));
            levelInfoList.Add(new LevelInfo(900, 2800, 22, 2, 6, 9));
            levelInfoList.Add(new LevelInfo(800, 2600, 24, 2, 6, 8));
            levelInfoList.Add(new LevelInfo(700, 2400, 26, 3, 7, 7));
            levelInfoList.Add(new LevelInfo(600, 2200, 28, 3, 7, 6));
            levelInfoList.Add(new LevelInfo(500, 2000, 30, 3, 7, 5));
            levelInfoList.Add(new LevelInfo(400, 1800, 32, 4, 7, 4));
            levelInfoList.Add(new LevelInfo(300, 1600, 34, 4, 8, 3));
            levelInfoList.Add(new LevelInfo(200, 1400, 36, 5, 8, 2));
            levelInfoList.Add(new LevelInfo(100, 1200, 38, 5, 9, 1));
            levelInfoList.Add(new LevelInfo(50, 1000, 40, 6, 9, 0));
            levelInfoList.Add(new LevelInfo(50, 800, 42, 6, 9, 0));
            levelInfoList.Add(new LevelInfo(50, 600, 44, 8, 10, 0));
            levelInfoList.Add(new LevelInfo(25, 400, 46, 8, 10, 0));
            levelInfoList.Add(new LevelInfo(0, 200, 48, 18, 20, 0));
        }


        public Vector3 GetShotPosition()
        {
            //if (myshots.Count != 0)
            //    return myshots[myshots.Count - 1].GetWorld().Translation;
            //else
                return Vector3.Zero;
        }
        
        public void AddShot(Vector3 position, Vector3 direction)
        {
            //myshots.Add(new Shots(Game.Content.Load<Model>(@"models\projektil"),
            //position, direction));
            //  myshots.Add(new Shots(Game.Content.Load<Model>(@"models\projektil"),
            //position, direction));\
            shots.Add(new SpinningEnemy(
            Game.Content.Load<Model>(@"models\turbosonic"),
            position, direction, 0, 0, 0,0.5f));
        }


       


        protected void UpdateShots( )
                {
                    // Loop through shots
                    for (int i = 0; i < shots.Count; ++i)
                    {
                        // Update each shot
                        shots[i].Update( );
                        // If shot is out of bounds, remove it from game
                        //if (shots[i].GetWorld( ).Translation.Z < shotMinZ)
                        //    {
                        //    shots.RemoveAt(i);
                        //    --i;
                        //    }
                    }
                    //for (int i = 0; i < myshots.Count; ++i)
                    //{
                    //    // Update each shot
                    //    myshots[i].Update();
                    //    // If shot is out of bounds, remove it from game
                    //    //if (shots[i].GetWorld( ).Translation.Z < shotMinZ)
                    //    //    {
                    //    //    shots.RemoveAt(i);
                    //    //    --i;
                    //    //    }
                    //}
                }

        
        //Get the world dimension for th eplayer Kobala
        public Matrix getKobalaWorld()
        {
            return myKobala.GetWorld();
        }
        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            // Set initial spawn time
            SetNextSpawnTime();
            //models.Add(new Kobala(Game.Content.Load<Model>(@"models\projektil"), new Vector3(0, 0, 0), Vector3.Zero));
            //initialize the main player
            SpawnKobala();
            base.Initialize();
        }

        public Vector3 GetModelPosition()
        {
            if (models.Count >= 1)
                return models[0].GetWorld().Translation;
            else
                return Vector3.Zero;
        }
        //public Vector3 GetShotPosition()
        //{
        //    if (shots.Count >= 1)
        //        return shots[shots.Count-1].GetWorld().Translation;
        //    else
        //        return Vector3.Zero;
        //}

        public Vector3 GetKobalaPosition()
        {

                return myKobala.GetWorld().Translation;

        }

        public Vector3 GetKobalaDirection()
        {

            return myKobala.GetKobalaDirection;

        }

        private void SetNextSpawnTime()
        {
            nextSpawnTime = ((Game1)Game).rnd.Next(
            levelInfoList[currentLevel].minSpawnTime,
            levelInfoList[currentLevel].maxSpawnTime);
            timeSinceLastSpawn = 0;
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            //Shoot
            //if (Keyboard.GetState().IsKeyDown(Keys.Space))
               // Shoot();
            // Check to see if it's time to spawn
            CheckToSpawnEnemy(gameTime);
            // Update models
            UpdateModels();

            // Update shots
            //UpdateShots();

            myKobala.Update();
            base.Update(gameTime);
        }
        public override void Draw(GameTime gameTime)
        {
            // Loop through and draw each model
            foreach (BasicModel bm in models)
            {
                bm.Draw(((Game1)Game).camera);
            }

            // Loop through and draw each shot
            foreach (BasicModel bm in shots)
            {
                bm.Draw(((Game1)Game).camera);
            }

            //// Loop through and draw each myshot
            //foreach (BasicModel bm in myshots)
            //{
            //    bm.Draw(((Game1)Game).camera);
            //}
            
            
            BasicModel Player= myKobala;
            Player.Draw(((Game1)Game).camera);


            base.Draw(gameTime);
        }
        protected void UpdateModels( )
        {
            //if (myKobala != null)
            //myKobala.Update();
            // Loop through all models and call Update
            for (int i = 0; i < models.Count; ++i)
            {
                // Update each model
                models[i].Update( );
                // Remove models that are out of bounds
                if (models[i].GetWorld().Translation.Z <
                    ((Game1)Game).camera.cameraPosition.Z - 100)
                {
                    models.RemoveAt(i);
                    --i;
                    nextenemy = false;
                }

                // //Remove models that are out of bounds
                //if (models[models.Count-1].GetWorld().Translation.Z <
                //    ((Game1)Game).camera.cameraPosition.Z - 100)
                //{
                //    nextenemy = false;
                //}

                
            }

        }
        protected override void LoadContent()
        {
            base.LoadContent();
            
        }


        protected void CheckToSpawnEnemy(GameTime gameTime)
        {
            //// Time to spawn a new enemy?
            //if (enemiesThisLevel <
            //levelInfoList[currentLevel].numberEnemies)
            //{
            //    timeSinceLastSpawn += gameTime.ElapsedGameTime.Milliseconds;
            //    if (timeSinceLastSpawn > nextSpawnTime)
            //    {
            //        SpawnEnemy();
            //    }
            //}
            if (nextenemy == false)
            {
                SpawnEnemy();
                nextenemy = true;
                //SpawnKobala();
            }

        }

        private void SpawnKobala()
        {
            myKobala = new Kobala(Game.Content.Load<Model>(@"models\p1_wedge"),new Vector3(0,-100,100),Vector3.Forward);
                 //Game.Content.Load<Model>(@"models\p1_wedge"),
                 //Vector3.Zero, Vector3.Zero, 0, 0, 0));
        }
        private void SpawnEnemy()
        {
            // Generate random position with random X and random Y
            // between -maxX and maxX and -maxY and maxY. Z is always
            // the same for all ships.
            //Vector3 position = new Vector3(((Game1)Game).rnd.Next(
            //-(int)maxSpawnLocation.X, (int)maxSpawnLocation.X),
            //((Game1)Game).rnd.Next(
            //-(int)maxSpawnLocation.Y, (int)maxSpawnLocation.Y),
            //maxSpawnLocation.Z);
            Vector3 position = new Vector3(0, 0,-5000);
            // Direction will always be (0, 0, Z), where
            // Z is a random value between minSpeed and maxSpeed
            Vector3 direction = new Vector3(0, 0,
            ((Game1)Game).rnd.Next(
            levelInfoList[currentLevel].minSpeed,
            levelInfoList[currentLevel].maxSpeed));
            //ector3 direction = new Vector3(0, 0, 5);
            // Get a random roll rotation between -maxRollAngle and maxRollAngle
            float rollRotation = (float)((Game1)Game).rnd.NextDouble() *
            maxRollAngle - (maxRollAngle / 2);
            // Add model to the list
            //models.Add(new SpinningEnemy(
            //Game.Content.Load<Model>(@"models\turbosonic"),
            //position, direction, 0, 0, rollRotation));


            //models.Add(new SpinningEnemy(
            //    Game.Content.Load<Model>(@"models\turbosonic"),
            //    position, direction,0, 0, rollRotation,1));
            //models.Add(new SpinningEnemy(
            //    Game.Content.Load<Model>(@"models\turbosonic"),
            //    new Vector3(-300,300,0), new Vector3(0,0,-10), 0, 0, MathHelper.PiOver4,0.2f));

            
            // Increment # of enemies this level and set next spawn time
            ++enemiesThisLevel;
            SetNextSpawnTime();
        }
       

    }
}
